home *** CD-ROM | disk | FTP | other *** search
/ BBS in a Box 4 / BBS in a Box - Macintosh - Volume IV (January 1992) (BBS in a Box).iso / Files / Prog / T / TransSkel2p.cpt / TransSkel ƒ.np / ManyWind ƒ / ManyWind.p
Encoding:
Text File  |  1988-12-09  |  7.1 KB  |  268 lines  |  [TEXT/PJMM]

  1. {    ManyWind TransSkel demonstration}
  2.  
  3. {    This application allows up to twenty windows to be created at once,}
  4. {    with the New item under the File menu.  The name of each window}
  5. {    appears under the Windows menu (which is not created until at least}
  6. {    one window exists).  Selecting the window name from the Windows menu}
  7. {    brings the window to the front.  For every window created, Skel is}
  8. {    told to create a new handler.  If the window's close box is clicked,}
  9. {    the handler removes the window name from the Windows menu, disposes}
  10. {    of the window, and removes itself from the window handler list.  If}
  11. {    the window was the last window, the Windows menu handler removes}
  12. {    itself from the menu handler list.}
  13.  
  14. {    When the first window is created, a Color menu also appears.  This}
  15. {    allows the color of the content region of the frontmost window to}
  16. {    be changed.  It goes away when the last window is closed.}
  17.  
  18. {    To quit, select Quit from the File menu or type command-Q.}
  19.  
  20. {    ManyWind demonstrates dynamic window and menu creation and disposal.}
  21. {    It also shows how handler procedures may be shared among handlers}
  22. {    for different windows.}
  23.  
  24. {    The project should include this file, TransSkel.p (or a library }
  25. {    built from TransSkel.p), Runtime.lib and Interface.lib .}
  26.  
  27. {    28 June 1986        Paul DuBois}
  28. {    7 January 1987 Owen Hartnett, Ωhm Software Co.    }
  29. {     6 June 1988 OH, changes for version 2.00 }
  30.  
  31. program ManyWind;
  32.  
  33.     uses
  34. {$IFC UNDEFINED THINK_PASCAL}
  35.         Memtypes, Quickdraw, OSIntf, ToolIntf, PackIntf, 
  36. {$ENDC}
  37.         TransSkel;
  38.  
  39.     const
  40.         maxWind = 20;    { maximum number of windows existing at once }
  41.  
  42.         aMenuNum = 1;    { Apple menu }
  43.         fMenuNum = 2;        { File menu }
  44.         wMenuNum = 3;        { Windows menu }
  45.         cMenuNum = 4;        { Color menu }
  46.  
  47.         new = 1;
  48.         quit = 3;
  49.  
  50.         cWhite = 1;
  51.         cLtGray = 2;
  52.         cGray = 3;
  53.         cDkGray = 4;
  54.         cBlack = 5;
  55.  
  56.     var
  57.         fileMenu, windowMenu, colorMenu: MenuHandle;
  58.  
  59.         windCount: integer;    { number of currently existing windows }
  60.         windNum: longint;    { id of last window created }
  61.  
  62.         dummy: Boolean;        { may be used for memory management }
  63.  
  64.     procedure MakeWindow;
  65.     forward;
  66.     procedure DoWClose;
  67.     forward;
  68.  
  69.     procedure DoWUpdate;
  70.  
  71.         var
  72.             thePort: GrafPtr;
  73.  
  74.     begin
  75.         GetPort(thePort);
  76.         EraseRect(thePort^.portRect);    { repaint w/background pattern }
  77.     end;
  78.  
  79.     procedure DoMClobber (theMenu: MenuHandle);
  80.  
  81.     begin
  82.         DisposeMenu(theMenu);
  83.     end;
  84.  
  85.     procedure DoFileMenu (item: integer);
  86.  
  87.     begin
  88.         case item of
  89.             quit: 
  90.                 SkelWhoa;        { tell SkelMain to quit }
  91.             new: 
  92.                 MakeWindow;    { make a new window }
  93.         end;
  94.     end;
  95.  
  96. {    Dispose of window.  Skel makes sure the port is pointing to the}
  97. {    appropriate window, so this procedure can determine which window}
  98. {    is to be disposed, of without being told explicitly.}
  99.  
  100.  
  101.     procedure DoWClobber;
  102.  
  103.         var
  104.             thePort: GrafPtr;
  105.  
  106.     begin
  107.         GetPort(thePort);                { grafport of window to dispose of }
  108.         DisposeWindow(WindowPtr(thePort));
  109.     end;
  110.  
  111. {    Change the background pattern of the frontmost window.  Ignore}
  112. {    if the front window is a DA window.}
  113.  
  114.     procedure DoColorMenu (item: integer);
  115.  
  116.         var
  117.             w: WindowPeek;
  118.             w2: WindowPtr;
  119.  
  120.     begin
  121.         w := WindowPeek(FrontWindow);
  122. {•  SetPort(WindowPtr(w));                {*** Fixed bug in original windows    •]}
  123.         if w^.windowKind >= 0 then             { front is not DA window }
  124.             begin
  125.                 case item of
  126.                     cWhite: 
  127.                         BackPat(white);
  128.                     cLtGray: 
  129.                         BackPat(ltGray);
  130.                     cGray: 
  131.                         BackPat(gray);
  132.                     cDkGray: 
  133.                         BackPat(dkGray);
  134.                     cBlack: 
  135.                         BackPat(black);
  136.                 end;
  137.                 w2 := WindowPtr(w);
  138.                 EraseRect(w2^.portRect);
  139.             end;
  140.     end;
  141.  
  142.  
  143.     procedure DoWindowMenu (item: integer);
  144.  
  145.         var
  146.             iTitle, wTitle: Str255;
  147.             w: WindowPeek;
  148.  
  149.     begin
  150.         GetItem(windowMenu, item, iTitle);     { get window name }
  151.         w := WindowPeek(FrontWindow);
  152.         while w <> nil do
  153.             begin
  154.                 GetWTitle(WindowPtr(w), wTitle);
  155.                 if EqualString(iTitle, wTitle, false, true) then
  156.                     begin
  157.                         SelectWindow(WindowPtr(w));
  158.                         w := nil;
  159.                     end;
  160.                 if w <> nil then
  161.                     w := w^.nextWindow;
  162.             end;
  163.     end;
  164.  
  165. {    Make new window.  Locate at (100, 100) if no other windows, else}
  166. {    offset slightly from front window.  The window title is the next}
  167. {    window number (1, 2, 3, ...).  If this is the first window, create}
  168. {    the Windows and Color menus.  Add the window title as the last item}
  169. {    of the Windows menu.}
  170.  
  171. {    If the maximum window count has been reached, disable New in the}
  172. {    File menu.}
  173.  
  174.     procedure MakeWindow;
  175.  
  176.         var
  177.             w: WindowPtr;
  178.             r, r2: Rect;
  179.             s: Str255;
  180.  
  181.     begin
  182.         SetRect(r, 0, 0, 200, 150);
  183.         w := FrontWindow;
  184.         if w = nil then
  185.             OffsetRect(r, 100, 100)
  186.         else
  187.             begin
  188.                 r2 := w^.portBits.bounds;
  189.                 OffSetRect(r, 20 - r2.left, 20 - r2.top);
  190.                 if (r.left > 480) or (r.top > 300) then    { keep on screen }
  191.                     OffsetRect(r, 40 - r.left, 40 - r.top);
  192.             end;
  193.         WindNum := windnum + 1;
  194.         NumToString(windNum, s);
  195.         w := NewWindow(nil, r, s, true, documentProc, WindowPtr(-1), true, 0);
  196.         dummy := SkelWindow(w, nil, nil, @DoWUpdate, nil, @DoWClose, @DoWclobber, nil, false);
  197.         windCount := windCount + 1;
  198.         if windCount - 1 = 0 then     { if first window, create new menus }
  199.             begin
  200.                 colorMenu := NewMenu(cMenuNum, 'Color');
  201.                 AppendMenu(colorMenu, 'White;Light Gray;Gray; Dark Gray; Black');
  202.                 dummy := SkelMenu(colorMenu, @DoColorMenu, @DoMClobber, false);
  203.                 windowMenu := NewMenu(wMenuNum, 'Windows');
  204.                 dummy := SkelMenu(windowMenu, @DoWindowMenu, @DoMClobber, true);
  205.             end;
  206.         AppendMenu(windowMenu, s);
  207.         if windCount = maxWind then
  208.             DisableItem(fileMenu, new);
  209.     end;
  210.  
  211. {    Mouse was clicked in close box.  Remove the window handler (which}
  212. {    causes the window to be disposed of), and delete the window title}
  213. {    from the Windows menu.  If the window was the last one, delete the}
  214. {    Windows and Color menus entirely.}
  215.  
  216. {    Skel makes sure the port is pointing to the appropriate window, so}
  217. {    this procedure can determine which window had its close box clicked,}
  218. {    without being told explicitly.}
  219.  
  220.     procedure DoWClose;
  221.  
  222.         var
  223.             thePort: GrafPtr;
  224.             m: MenuHandle;
  225.             i, mItems: integer;
  226.             iTitle, wTitle: Str255;
  227.  
  228.     begin
  229.         GetPort(thePort);            { grafport of window to be closed }
  230.         GetWTitle(WindowPtr(thePort), wTitle);
  231.         SkelRmveWind(WindowPtr(thePort));
  232.         windCount := windCount - 1;
  233.         if windCount = 0 then
  234.             begin
  235.                 SkelRmveMenu(windowMenu);    { last window - clobber menus }
  236.                 SkelRmveMenu(colorMenu);
  237.             end
  238.         else
  239.             begin    { just take out of menu }
  240.                 m := NewMenu(wMenuNum, 'Windows');
  241.                 mItems := CountMItems(windowMenu);
  242.                 for i := 1 to mItems do
  243.                     begin
  244.                         GetItem(windowMenu, i, iTitle);
  245.                         if not EqualString(iTitle, wTitle, false, true) then
  246.                             AppendMenu(m, iTitle);
  247.                     end;
  248.                 SkelRmveMenu(windowMenu);    { remove old Windows menu }
  249.                 windowMenu := m;                { and install new one }
  250.                 dummy := SkelMenu(windowMenu, @DoWindowMenu, @DoMClobber, true);
  251.             end;
  252.         EnableItem(fileMenu, new);    { can always create at least one more now }
  253.     end;
  254.  
  255.  
  256. begin
  257.  
  258.     WindCount := 0;
  259.     WindNum := 0;
  260.     SkelInit(6, nil);                                            { initialize }
  261.     SkelApple('', nil);                                { handle desk accessories }
  262.     fileMenu := NewMenu(fMenuNum, 'File');        { make File menu handler }
  263.     AppendMenu(fileMenu, 'New/N;(-;Quit/Q');
  264.     SkelGrowBounds(nil, 50, 10, 500, 300);
  265.     dummy := SkelMenu(fileMenu, @DoFileMenu, @DoMClobber, true);
  266.     SkelMain;                                        { loop 'til Quit selected }
  267.     SkelClobber;                                    { clean up }
  268. end.